package com.xiaoshuidi.cloud.module.iot.controller.admin;

import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.module.iot.common.ResultModel;
import com.xiaoshuidi.cloud.module.iot.controller.admin.doorlock.vo.*;
import com.xiaoshuidi.cloud.module.iot.controller.admin.lyimport.LeiYouImportReq;
import com.xiaoshuidi.cloud.module.iot.dal.model.account.CategorysByBrandVo;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbAccountDo;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbDeviceDo;
import com.xiaoshuidi.cloud.module.iot.enums.ApiConstants;
import com.xiaoshuidi.cloud.module.iot.enums.ErrorCodeEnum;
import com.xiaoshuidi.cloud.module.iot.service.LocalDeviceService;
import com.xiaoshuidi.cloud.module.iot.service.MeChantAccountService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 设备相关接口
 * @author Sky
 * create 2019/04/15
 * email sky.li@ixiaoshuidi.com
 **/
@RestController
@Tag(name = "智能设备 - 关联设备")
@RequestMapping(ApiConstants.NAME + "/device")
public class DeviceController {

    private final static Logger LOGGER = LoggerFactory.getLogger(DeviceController.class);

    @Autowired
    private LocalDeviceService localDeviceService;
    @Autowired
    private MeChantAccountService meChantAccountService;


    /**
     * 根据第三方login_name,login_key 拉取设备并存入IOT库
     *
     * @return
     */
    @Operation(summary = "根据第三方login_name,login_key 拉取设备并存入IOT库")
    @Parameter(name = "tbAccountModels", description = "水表请求实体")
    @PostMapping("/setDeviceList/LnLk")
    public ResultModel saveDeviceListToIOTByLnLk(@RequestBody List<TbAccountDo> tbAccountModels) {
        ResultModel resultModel = null;
        try {
            resultModel = localDeviceService.saveDeviceListToIOTByLnLk(tbAccountModels);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据第三方login_name,login_key 拉取设备并存入IOT库异常,请求参数:{},异常原因:{}", JSONObject.toJSONString(tbAccountModels), e);
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }

    /**
     * 根据水滴api_no拉取设备并存入IOT库
     *
     * @return
     */
    @Operation(summary = "根据水滴api_no拉取设备并存入IOT库")
    @PostMapping("/setDeviceList/apiNo")
    @PreAuthorize("@ss.hasAnyPermissions('iot:device:set-devcie-list')")
    public ResultModel saveDeviceListToIOTByApiNo() {
        ResultModel resultModel = null;
        try {
            List<String> apiNos = meChantAccountService.getApiNosByUserId();
            if(apiNos.size()==0){
                return ResultModel.createNativeFail(ErrorCodeEnum.ADD_DEVICE_ERROR.getMsg());
            }
            resultModel = localDeviceService.saveDeviceListToIOTByApiNo(apiNos);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据水滴api_no拉取设备并存入IOT库异常,异常原因:{}", e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }


    /**
     * 根据品牌编号查询该品牌对接品类
     *
     * @param brandNo
     * @return
     */
    @Operation(summary = "根据品牌编号查询该品牌对接品类")
    @Parameter(name = "brandNo", description = "品牌编号")
    @GetMapping("/brand/getCategory")
    public ResultModel<List<CategorysByBrandVo>> getCategoryByBrand(@RequestParam("brandNo") String brandNo) {
        ResultModel<List<CategorysByBrandVo>> categoryByBrand = null;
        try {
            categoryByBrand = localDeviceService.getCategoryByBrand(brandNo);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据品牌编号查询该品牌对接品类,请求参数:{},异常原因:{}", brandNo, e.getMessage());
            categoryByBrand = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return categoryByBrand;
    }

    /**
     * 根据水滴api_no拉取设备列表并展示给第三方
     *
     * @param apiNos
     * @return
     */
    @Operation(summary = "根据水滴api_no拉取设备列表并展示给第三方")
    @Parameter(name = "apiNos", description = "品牌编号")
    @PostMapping("/getDeviceList/apiNo")
    public ResultModel<Map<String, List<PullDeviceVo>>> getDeviceListByApiNo(@RequestBody List<String> apiNos) {
        ResultModel<Map<String, List<PullDeviceVo>>> resultModel = null;
        try {
            resultModel = localDeviceService.getDeviceListByApiNo(apiNos);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据水滴api_no拉取设备并存入IOT库异常,请求参数:{},异常原因:{}", JSONObject.toJSONString(apiNos), e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }

    /**
     * 根据device_name模糊查询设备列表（品类）
     *
     * @param tbDeviceDo
     * @return
     */
    @Operation(summary = "根据device_name模糊查询设备列表（品类）")
    @Parameter(name = "tbDeviceDo", description = "设备实体类")
    @PostMapping("/getDeviceList/deviceName")
    public ResultModel<List<PullDeviceVo>> getDevcieListByDeviceName(@RequestBody TbDeviceDo tbDeviceDo) {
        ResultModel<List<PullDeviceVo>> resultModel = null;
        try {
            resultModel = localDeviceService.getDevcieListByDeviceName(tbDeviceDo);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据device_name模糊查询设备列表异常,请求参数:{},异常原因:{}", JSONObject.toJSONString(tbDeviceDo), e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }

    /**
     * 根据device_no 列表批量查询设备列表
     *
     * @param deviceListByNosReqVO
     * @return
     */
    @Operation(summary = "根据device_no 列表批量查询设备列表")
    @Parameter(name = "deviceListByNosReqVO", description = "设备列表实体类")
    @PostMapping("/getDeviceList/deviceNos")
    public ResultModel<List<PullDeviceVo>> getDeviceListByDeviceNos(@RequestBody DeviceListByNosReqVO deviceListByNosReqVO, @RequestHeader Integer userId) {
        ResultModel<List<PullDeviceVo>> resultModel = null;
        try {
            deviceListByNosReqVO.setUserId(userId);
            resultModel = localDeviceService.getDeviceListByDeviceNos(deviceListByNosReqVO);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据device_no 列表批量查询设备列表,请求参数:{},异常原因:{}", JSONObject.toJSONString(deviceListByNosReqVO), e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }

    /**
     * 根据device_no 列表,批量清空设备剩余金额
     *
     * @param deviceNos
     * @return
     */
    @Operation(summary = "根据device_no 列表,批量清空设备剩余金额")
    @Parameter(name = "deviceNos", description = "设备充值金额清零请求对象")
    @PostMapping("/manage/setChargeFeeClear")
    public ResultModel<DeviceChargeFeeClearResVO> setChargeFeeClear(@RequestBody List<DeviceChargeFeeClearReqVO> deviceNos) {
        ResultModel<DeviceChargeFeeClearResVO> resultModel = null;
        try {
            resultModel = localDeviceService.setChargeFeeClear(deviceNos);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据device_no 列表,批量清空设备剩余金额,请求参数:{},异常原因:{}", JSONObject.toJSONString(deviceNos), e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }

    /**
     * 根据device_no 列表,批量入住退租
     *
     * @param deviceResideListReqVOS
     * @return
     */
    @Operation(summary = "根据device_no 列表,批量入住退租")
    @Parameter(name = "deviceResideListReqVOS", description = "设备入住请求对象")
    @PostMapping("/manage/setListResideStatus")
    public ResultModel<DeviceResideListResVO> setListResideStatus(@RequestBody List<DeviceResideListReqVO> deviceResideListReqVOS) {
        ResultModel<DeviceResideListResVO> resultModel = null;
        try {
            resultModel = localDeviceService.setListResideStatus(deviceResideListReqVOS);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据device_no 列表,批量入住退租,请求参数:{},异常原因:{}", JSONObject.toJSONString(deviceResideListReqVOS), e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }


    /**
     * 请求第三方获取第三方数据库中水电表读数
     */
    @Operation(summary = "请求第三方获取第三方数据库中水电表读数")
    @Parameter(name = "deviceGetDailyPowerReqModel", description = "对电表读数请求对象")
    @PostMapping("/manage/getDailyPower")
    public ResultModel<List<DeviceGetDailyPowerResModel>> getDailyPower(@RequestBody DeviceGetDailyPowerReqModel deviceGetDailyPowerReqModel) {
        ResultModel<List<DeviceGetDailyPowerResModel>> resultModel = null;
        try {
            resultModel = localDeviceService.getDailyPower(deviceGetDailyPowerReqModel);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz-定时任务获取第三方水电表数据（第三方数据库）请求参数：{}，异常原因：{}", JSONObject.toJSONString(deviceGetDailyPowerReqModel), e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }

    /**
     * 根据device_no 列表批量查询设备列表
     *
     * @param deviceListByNosReqVO
     * @return
     */
    @Operation(summary = "根据device_no 列表批量查询设备列表")
    @Parameter(name = "deviceListByNosReqVO", description = "对电表读数请求对象")
    @PostMapping("/findDeviceList/deviceNos")
    public ResultModel<List<PullDeviceVo>> findDeviceListByDeviceNos(@RequestBody DeviceListByNosReqVO deviceListByNosReqVO) {
        ResultModel<List<PullDeviceVo>> resultModel = null;
        try {
            resultModel = localDeviceService.findDeviceListByDeviceNos(deviceListByNosReqVO);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("biz->根据device_no 列表批量查询设备列表,请求参数:{},异常原因:{}", JSONObject.toJSONString(deviceListByNosReqVO), e.getMessage());
            resultModel = ResultModel.createNativeFail(ErrorCodeEnum.SYSTEM_EXCEPTION.getMsg());
        }
        return resultModel;
    }

    /**
     * 导入雷优设备列表
     *
     * @param req
     * @return
     */
    @Operation(summary = "导入雷优设备列表")
    @Parameter(name = "req", description = "请求对象含apiNo和file文件字段")
    @PostMapping("/import/leiYouDevices")
    public ResultModel importLeiYouDevices(LeiYouImportReq req) {
        return localDeviceService.saveLeiYouDeviceFromExcel(req.getApiNo(), req.getFile());
    }

}
